/**
 * Created by jingqing.zhou on 2015/4/25.
 *
 */

/**
 * 根命名空间
 * @type {{}}
 */
window.dep = {};

/**
 * 命名空间构造函数
 * dep.Namespace("dep.ui.alert")
 * @param ns
 * @constructor
 * @return 返回根据命名空间创建的对象
 */

dep.Namespace = function(ns){
    var root =window ;
    var parts = ns.split(".");
    var part = "";
    for(var i=0;i<parts.length;i++){
        part = parts[i];
        if(!root[part]){
            root[part]={};
        }
        root = root[part]; //这样子相当于每当我们调用dep.Namespace方法（如dep.Namespace(a.b.c)）时，相当于创建了层层嵌套的3个{}对象,就可以使用对象.属性的方法进行对象间访问了
    }
  return root ;
}

/**
 *对象继承工具类
 */
dep.extend = function(subClass,superClass){
    subClass.prototype = new superClass();//让子类的原型对象等于父类的实例对象 相当于子类拥有了父类原型上的各种方法
    subClass.prototype.constructor = subClass ;//由于上一行的继承方式会导致子类原型上的构造方法也指向父类，这里要进行更正
    subClass.superclass = superClass ;
    if(superClass.prototype.constructor == Object.prototype.constructor){
        superClass.prototype.constructor = superClass ;
    }
    return subClass;
}

/**
 * 事件处理类
 */
dep.Event = function(){
    /**
     * 添加事件监听
     * @param {String} name 事件名称
     * @param {Function}catcher 事件处理函数
     * @param callObj 调用事件的对象
     * @returns{String} 返回事件注册ID
     */
    this.attachEvent = function(name,catcher,callObj){
        name = 'ev_'+name.toLowerCase();
        if(!this[name]){
            this[name]= new this.eventCather(callObj||this);
        }
        return(name+':'+this[name].addEvent(catcher)); //return ID (event name & event ID)//TODO 这里的addEvent指向不清楚
    }
    /**
     *  获取事件处理函数
     *  @function
     *  @private
     *  @param {Object} obj 事件名称
     *  @return {Function}  返回事件处理函数
     **/
    this.eventCather = function(obj){
        var catchs = [] ;
        /**
         * @ignore 加上这个注释后注释文档会忽略这段代码
         */
        var z = function(){
            var res =true ;
            for(var i=0;i<catchs.length;i++){
                if(catchs[i]!=null){
                    var zr = catchs[i].apply(obj,arguments);
                    res = res&&zr;
                }
            }
            return res ;
        }
        /**
         * @ignore
         * @param ev
         */
        z.attachEvent = function (ev){
            if (typeof (ev) != "function")
                ev=eval(ev);//TODO 无法理解
            if (ev)
                return catchs.push(ev)-1;
            return false;
        }

        /**
         * @ignore
         */
        z.removeEvent=function(id){
            catchs[id]=null;
        };
        return z;
    }

    /**
     *  派发事件方法
     *  @function
     *  @param {String} name 事件名称
     *  @param {Function} argumnet 事件回调处理参数
     *  @returns {} 返回事件回调函数的返回值
     **/
    this.dispatchEvent=function(name, arg0){
        name='ev_'+name.toLowerCase();
        if (this[name]){
            return this[name].apply(this, arg0);
        }
        return true;
    };

    /**
     *  检查事件是否注册
     *  @function
     *  @param {String} name 事件名称
     *  @param {Function} argumnet 事件回调处理参数
     **/
    this.checkEvent=function(name){
        return (!!this['ev_'+name.toLowerCase()]);
    };

    /**
     *  取消事件监听
     *  @function
     *  @param {String} id 事件ID
     *  @return {}  返回事件处理函数
     **/
    this.detachEvent=function(id){
        if (id != false){
            var list = id.split(':');           //get EventName and ID
            this[list[0]].removeEvent(list[1]); //remove event
        }
    };
    /**
     *  取消所有事件监听
     *  @function
     *  @return {}  返回事件处理函数
     **/
    this.detachAllEvents = function(){
        for (var name in this){
            if (name.indexOf("ev_")==0)
                delete this[name];
        }
    };

}

/**
 * 获取事件
 */
dep.Event.getEvent = function() {     //同时兼容ie和ff的写法
   if(document.all){
      return window.event;
       func = dep.Event.getEvent.caller;//用来判断是否存在于上级函数
   }
    while(func!=null){//阻止事件冒泡
        var arg0=func.arguments[0];
        if(arg0){
            if((arg0.constructor==Event || arg0.constructor ==MouseEvent)
                || (typeof(arg0)=="object" && arg0.preventDefault && arg0.stopPropagation)){
                return arg0;
            }
        }
        func = func.caller;
    }
    return null;
}

/**
 * 阻止事件
 * @param event 事件对象
 */
dep.Event.stopEvent = function(event){
    dep.Event.stopPropagation(event);
    dep.Event.preventDefault(event);
};
/**
 * 阻止事件冒泡
 * @param event 事件对象
 */
dep.Event.stopPropagation = function(event){
    if (event.stopPropagation) {
        event.stopPropagation();
    } else {
        event.cancelBubble = true;
    }
};
/**
 * 阻止浏览器默认事件触发
 * @param event 事件对象
 */
dep.Event.preventDefault = function(event){
    if (event.preventDefault) {
        event.preventDefault();
    } else {
        event.returnValue = false;
        // Some keys events require setting the keyCode to -1 to be prevented
        try {
            // all ctrl + X and F1 -> F12
            if (event.ctrlKey || event.keyCode > 111 && event.keyCode < 124) {
                event.keyCode = -1;
            }
        } catch (e) {
            // see this outdated document http://support.microsoft.com/kb/934364/en-us for more info
        }
    }
};

/***
 * 基类：所有对象父类
 * @class
 * @author zehui.zeng
 */
dep.Base = function(){
    dep.Base.superclass.constructor.call(this,{});
    /**
     * 值设置
     * @param field 字段名称
     * @param value 字段值
     */
    this.set = function(field,value){
        this[field] = value;
    };
    /**
     * 值获取
     * @param field 字段名称
     */
    this.get = function(field){
        return this[field];
    };
    /**
     *  转换JSON字符串
     *  @returns {String} 返回JSON字段串
     */
    this.toJsonString = function(){
        var f = {};
        for(var o in this){
            if(typeof(this[o]) !='function'){
                f[o] = JSON.parse(JSON.stringify(this[o]));
            }
            f[o] = this.replaceSpecialCharacters(f[o]);
        }
        return JSON.stringify(f);
    };

    /**
     *  JSON字符串特殊字符转码
     *  @param {Object} obj 包含要转码字符的对象
     *  @returns {Object} 返回转码后的对象
     */
    this.replaceSpecialCharacters = function(obj){
        if (typeof (obj) != "object") {
            return obj;
        }
        for ( var key in obj) {
            if (typeof (obj[key]) == 'object') {
                obj[key] = this.replaceSpecialCharacters(obj[key]);
            } else if(typeof(obj[key]) == "string"){
                obj[key] = obj[key].replace(/\\/g,'\\\\').replace(/\"/g,'\\\"');
                obj[key] = encodeURIComponent(obj[key]);
            }else{
                obj[key] = encodeURIComponent(obj[key]);//数字转码成string
            }
        }
        return obj;
    };
};
dep.extend(dep.Base,dep.Event);

/**
 * 错误处理类
 *
 * @class
 * @param {json}
 *            config 构造参数
 * @author zehui.zeng
 *
 * @example throw new dep.Error("出错啦！"); 或 throw new dep.Error("功能错误","出错啦！"); 或
 *          throw new dep.Error({name:"功能错误",message:"出错啦！"});
 */
dep.Error = function(config){
    /**
     *  错误名称
     */
    this.name = "";
    /**
     *  错误消息
     */
    this.message = "";
    /**
     *  错误描述 仅 IE8 支持。
     */
    this.description = "";
    /**
     *	错误行号，仅 Safari 支持。
     */
    this.line = "";
    /**
     *	错误编号，例如“缺少对象”是 -2146823281。“xx未定义”是 -2146823279。仅 IE 支持。
     */
    this.number = "";
    /**
     *	错误发生所在行号，仅 Firefox 支持。
     */
    this.lineNumber = "";
    /**
     *	发生错误的所在文件地址，仅 Firefox 支持。
     */
    this.fileName = "";
    /**
     *	发生错误的所在文件地址，仅 Firefox 支持。
     */
    this.stack = "";


    if(arguments.length = 1){
        if(Object.prototype.toString.call(config) == "[object Object]"){
            $.extend(this,config);
        }else{
            this.message = config;
        }
    }else if(arguments.length = 2){
        this.name = arguments[0];
        this.message = arguments[1];
    }else{
        $.extend(this,config);
    }
};


/**
 * 常量类
 * @name dep.constant
 * @namespace 常量类
 * @version v1.0
 **/
dep.Namespace("dep.constant");

/**
 * 工具包
 * @name dep.utils
 * @namespace 工具包
 * @version v1.0
 **/
dep.Namespace("dep.utils");

/**
 * dep.data 包
 * @name dep.data
 * @namespace 数据处理包
 **/
dep.Namespace("dep.data");

/***
 * 请求处理对象包
 * @name dep.request
 * @namespace 请求处理对象包
 * @author zehui.zeng
 **/
dep.Namespace("dep.request");

/**
 * ui组件包
 * @name dep.ui
 * @namespace ui组件包
 * @author zehui.zeng
 **/
dep.Namespace("dep.ui");

/**
 * 树控件
 * @name dep.ui.tree
 * @namespace 树控件
 * @author minzhong.xu
 **/
dep.Namespace("dep.ui.tree");

/**
 * 列表控件
 * @name dep.ui.grid
 * @namespace 列表控件
 * @author zehui.zeng
 **/
dep.Namespace("dep.ui.grid");

/**
 * 工具栏控件
 * @name dep.ui.toolbar
 * @namespace 工具栏控件
 * @author xli
 **/
dep.Namespace("dep.ui.toolbar");

/**
 * 选项卡控件
 * @name dep.ui.tabbar
 * @namespace 选项卡控件
 * @author xli
 **/
dep.Namespace("dep.ui.tabbar");


/**
 * 图表控件
 * @name dep.ui.chart
 * @namespace 图表控件
 * @author zehui.zeng
 **/
dep.Namespace("dep.ui.chart");

/**
 * 查询组件
 * @name dep.ui.query
 * @namespace 查询组件
 * @author zehui.zeng
 **/
dep.Namespace("dep.ui.query");

/**
 * 选择组件
 * @name dep.ui.selector
 * @namespace 选择组件
 * @author zehui.zeng
 **/
dep.Namespace("dep.ui.selector");

/**
 * 图表组件
 * @name dep.ui.chart
 * @namespace 图表组件
 * @author zehui.zeng
 **/
dep.Namespace("dep.ui.chart");

/**
 * 门户组件
 * @name dep.ui.portal
 * @namespace 门户组件
 * @author panliang.xiao
 **/
dep.Namespace("dep.ui.portal");
